package com.rabbiter.oes.config;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.rabbiter.oes.entity.Student1;
import com.rabbiter.oes.service.Student1Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class EasyExcelConfig implements ReadListener<Student1> {


    private final Student1Service student1Service;
    /*成功数据*/
    private final CopyOnWriteArrayList<Student1> successList = new CopyOnWriteArrayList<>();
    //总条数
    private final AtomicInteger total = new AtomicInteger();
    /*单次处理条数*/
    private final static int BATCH_COUNT = 20000;
   private int processors = Runtime.getRuntime().availableProcessors();
    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(processors +1, processors * 2+1, 10 * 60L,  TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000000));

    public EasyExcelConfig(Student1Service student1Service) {
        this.student1Service = student1Service;
    }


    @Override
    public void invoke(Student1 student1, AnalysisContext analysisContext) {
            successList.add(student1);
        if(successList.size() >= BATCH_COUNT){
            log.info("读取数据：{}", successList.size());
            saveData();
        }

    }

    /**
     * 采用多线程读取数据
     */
    private void saveData() {
        List<List<Student1>> lists = ListUtil.split(successList, 20000);
        CountDownLatch countDownLatch = new CountDownLatch(lists.size());
        for (List<Student1> list : lists) {
            threadPoolExecutor.execute(()->{
                try {
                    student1Service.addList(list);
                    total.addAndGet(successList.size());
                } catch (Exception e) {
                    log.error("启动线程失败,e:{}", e.getMessage(), e);
                } finally {
                    //执行完一个线程减1,直到执行完
                    countDownLatch.countDown();
                }
            });
        }
        // 等待所有线程执行完
        try {
            countDownLatch.await();
        } catch (Exception e) {
            log.error("等待所有线程执行完异常,e:{}", e.getMessage(), e);
        }
        // 提前将不再使用的集合清空，释放资源
        successList.clear();
        lists.clear();
    }

    /**
     * 所有数据读取完成之后调用
     *
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //读取剩余数据
            log.info("读取数据：{}条",successList.size());
            saveData();
    }

    //成功
    public int getSuccessCount() {
        return total.get();
    }
}